from datetime import datetime
from typing import Optional, List

from fastapi.exceptions import HTTPException

from app.core.crud import CRUDBase
from app.models.admin import User
from app.schemas.login import CredentialsSchema
from app.schemas.users import UserCreate, UserUpdate
from app.utils.password import get_password_hash, verify_password


class UserController(CRUDBase[User, UserCreate, UserUpdate]):

    def __init__(self):
        super().__init__(User)

    async def get_by_email(self, email: str) -> Optional[User]:
        return await self.model.filter(email=email).first()

    async def get_by_username(self, username: str) -> Optional[User]:
        return await self.model.filter(username=username).first()

    async def create(self, obj_in: UserCreate) -> User:
        obj_in.password = get_password_hash(obj_in.password)
        obj = await super().create(obj_in.create_dict())
        return obj

    async def update(self, obj_in: UserUpdate) -> User:
        obj = await super().update(id=obj_in.id, obj_in=obj_in.update_dict())
        return obj

    async def delete(self, id: int) -> User:
        obj = await super().delete(id)

    async def update_last_login(self, id: int) -> None:
        user = await self.model.get(id=id)
        user.last_login = datetime.now()
        await user.save()

    async def authenticate(self,
                           credentials: CredentialsSchema) -> Optional[User]:
        user = await self.model.filter(username=credentials.username).first()
        if not user:
            raise HTTPException(status_code=400,
                                detail="Incorrect username or password")
        verified = verify_password(credentials.password, user.password)
        if not verified:
            raise HTTPException(status_code=400,
                                detail="Incorrect username or password")
        return user


user_controller = UserController()
